package com.example.chamberlainserver.Service.impl;

import com.example.chamberlainserver.Entry.User;
import com.example.chamberlainserver.Entry.UserActionLog;
import com.example.chamberlainserver.Entry.UserLoginLog;
import com.example.chamberlainserver.Service.UserLogService;
import com.example.chamberlainserver.dto.PageResult;
import com.example.chamberlainserver.dto.UserActionLogQueryDTO;
import com.example.chamberlainserver.dto.UserLoginLogQueryDTO;
import com.example.chamberlainserver.mapper.UserActionLogMapper;
import com.example.chamberlainserver.mapper.UserLoginLogMapper;
import com.example.chamberlainserver.mapper.UserMapper;
import com.example.chamberlainserver.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 用户日志服务实现类
 */
@Service
public class UserLogServiceImpl implements UserLogService {
    
    @Autowired
    private UserLoginLogMapper loginLogMapper;
    
    @Autowired
    private UserActionLogMapper actionLogMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public void recordUserLogin(int userId, String ip, int status, String message, String userAgent) {
        UserLoginLog loginLog = new UserLoginLog();
        loginLog.setUserId(userId);
        loginLog.setLoginIp(ip);
        loginLog.setLoginStatus(status == 1); // 将int类型的status转换为Boolean
        loginLog.setFailReason(status == 0 ? message : null); // 如果状态为0，设置失败原因
        loginLog.setLoginTime(LocalDateTime.now());
        loginLog.setCreateTime(LocalDateTime.now());
        
        // 根据userId获取用户名
        String username = "未知用户";
        if (userId > 0) {
            try {
                User user = userMapper.getUserById(userId);
                if (user != null && user.getStuNo() != null) {
                    username = user.getStuNo();
                }
            } catch (Exception e) {
                // 获取用户信息失败，使用默认用户名
            }
        }
        
        loginLog.setUsername(username);
        
        // 设置登录设备信息
        String loginDevice = "未知设备";
        if (userAgent != null && !userAgent.isEmpty()) {
            loginDevice = parseUserAgent(userAgent);
        }
        loginLog.setLoginDevice(loginDevice);
        
        loginLogMapper.insert(loginLog);
    }
    
    @Override
    public void recordUserLogout(Long loginLogId) {
        if (loginLogId == null) {
            return;
        }
        
        LocalDateTime logoutTime = LocalDateTime.now();
        
        // 获取登录日志
        List<UserLoginLog> loginLogs = loginLogMapper.getLoginLogsByUserId(loginLogId.intValue(), 1);
        if (loginLogs.isEmpty()) {
            return;
        }
        
        UserLoginLog loginLog = loginLogs.get(0);
        LocalDateTime loginTime = loginLog.getLoginTime();
        
        // 计算会话时长（秒）
        long sessionDuration = Duration.between(loginTime, logoutTime).getSeconds();
        
        // 更新登出信息
        loginLogMapper.updateLogout(loginLogId, logoutTime, sessionDuration);
    }
    
    @Override
    public void recordUserAction(int userId, String username, String userRole, String module, String operation,
                                String description, String method, String requestUrl, String requestIp, 
                                String requestParams, Boolean status, String errorMsg, Long duration) {
        // 检查用户ID是否有效
        if (userId <= 0) {
            System.out.println("用户ID无效，跳过记录用户操作日志: userId=" + userId);
            return;
        }
        
        // 验证用户ID是否存在于user表中
        try {
            User user = userMapper.getUserById(userId);
            if (user == null) {
                System.out.println("用户ID在数据库中不存在，跳过记录用户操作日志: userId=" + userId);
                return;
            }
        } catch (Exception e) {
            System.err.println("验证用户ID时发生异常，跳过记录用户操作日志: " + e.getMessage());
            return;
        }
        
        UserActionLog actionLog = new UserActionLog();
        actionLog.setUserId(userId);
        actionLog.setUsername(username);
        actionLog.setUserRole(userRole);
        actionLog.setModule(module);
        actionLog.setOperation(operation);
        actionLog.setDescription(description);
        actionLog.setMethod(method);
        actionLog.setRequestUrl(requestUrl);
        actionLog.setRequestIp(requestIp);
        actionLog.setRequestParams(requestParams);
        actionLog.setStatus(status);
        actionLog.setErrorMsg(errorMsg);
        actionLog.setOperateTime(LocalDateTime.now());
        actionLog.setDuration(duration);
        actionLog.setCreateTime(LocalDateTime.now());
        
        actionLogMapper.insert(actionLog);
    }
    
    @Override
    public Map<String, Object> getLoginStats(LocalDateTime startTime, LocalDateTime endTime) {
        // 获取登录总数
        int totalLogins = loginLogMapper.getLoginCountByTimeRange(startTime, endTime);
        
        // 获取独立用户数
        int uniqueUsers = loginLogMapper.getUniqueUserCountByTimeRange(startTime, endTime);
        
        // 计算人均登录次数
        double averageLoginsPerUser = uniqueUsers > 0 ? (double) totalLogins / uniqueUsers : 0;
        
        // 获取每日登录次数
        List<Map<String, Object>> timeDistribution = loginLogMapper.getDailyLoginCounts(startTime, endTime);
        
        Map<String, Object> result = new HashMap<>();
        result.put("totalLogins", totalLogins);
        result.put("uniqueUsers", uniqueUsers);
        result.put("averageLoginsPerUser", averageLoginsPerUser);
        result.put("timeDistribution", timeDistribution);
        
        return result;
    }
    
    @Override
    public List<Map<String, Object>> getOperationDistribution(LocalDateTime startTime, LocalDateTime endTime) {
        // 获取操作分布
        List<Map<String, Object>> operationDistribution = actionLogMapper.getOperationDistribution(startTime, endTime);
        
        // 获取操作总数
        int totalCount = actionLogMapper.getActionCountByTimeRange(startTime, endTime);
        
        // 计算百分比
        for (Map<String, Object> item : operationDistribution) {
            int count = ((Number) item.get("count")).intValue();
            int percentage = totalCount > 0 ? (count * 100 / totalCount) : 0;
            item.put("percentage", percentage);
        }
        
        return operationDistribution;
    }
    
    @Override
    public List<Map<String, Object>> getDailyLoginCounts(LocalDateTime startTime, LocalDateTime endTime) {
        return loginLogMapper.getDailyLoginCounts(startTime, endTime);
    }
    
    @Override
    public PageResult<UserActionLog> pageActionLogs(UserActionLogQueryDTO queryDTO) {
        // 使用PageUtils处理分页参数
        int[] pageParams = PageUtils.handlePageParam(queryDTO.getPageNum(), queryDTO.getPageSize());
        int pageNum = pageParams[0];
        int pageSize = pageParams[1];
        
        // 使用PageHelper进行分页查询
        com.github.pagehelper.Page<UserActionLog> page = com.github.pagehelper.PageHelper.startPage(pageNum, pageSize)
                .doSelectPage(() -> actionLogMapper.pageActionLogs(queryDTO));
        
        // 构建分页结果
        return PageUtils.buildPageResult(pageNum, pageSize, page.getTotal(), page.getResult());
    }
    
    /**
     * 解析User-Agent字符串，提取设备和浏览器信息
     * @param userAgent User-Agent字符串
     * @return 格式化后的设备和浏览器信息
     */
    private String parseUserAgent(String userAgent) {
        if (userAgent == null || userAgent.isEmpty()) {
            return "未知设备";
        }
        
        // 提取操作系统信息
        String os = "未知操作系统";
        Pattern osPattern = Pattern.compile("\\((.*?)\\)");
        Matcher osMatcher = osPattern.matcher(userAgent);
        if (osMatcher.find()) {
            String osInfo = osMatcher.group(1);
            if (osInfo.contains("Windows")) {
                os = "Windows";
                if (osInfo.contains("Windows NT 10.0")) os = "Windows 10";
                else if (osInfo.contains("Windows NT 6.3")) os = "Windows 8.1";
                else if (osInfo.contains("Windows NT 6.2")) os = "Windows 8";
                else if (osInfo.contains("Windows NT 6.1")) os = "Windows 7";
            } else if (osInfo.contains("Mac OS X")) {
                os = "Mac OS";
            } else if (osInfo.contains("Linux")) {
                os = "Linux";
            } else if (osInfo.contains("Android")) {
                os = "Android";
            } else if (osInfo.contains("iPhone") || osInfo.contains("iPad")) {
                os = "iOS";
            }
        }
        
        // 提取浏览器信息
        String browser = "未知浏览器";
        if (userAgent.contains("Chrome") && !userAgent.contains("Edg") && !userAgent.contains("OPR")) {
            browser = "Chrome";
        } else if (userAgent.contains("Firefox")) {
            browser = "Firefox";
        } else if (userAgent.contains("Safari") && !userAgent.contains("Chrome")) {
            browser = "Safari";
        } else if (userAgent.contains("Edg")) {
            browser = "Edge";
        } else if (userAgent.contains("OPR") || userAgent.contains("Opera")) {
            browser = "Opera";
        } else if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            browser = "Internet Explorer";
        }
        
        return os + " / " + browser;
    }
    
    @Override
    public List<Map<String, Object>> getModuleDistribution(LocalDateTime startTime, LocalDateTime endTime) {
        // 如果未指定时间范围，默认查询最近30天
        if (startTime == null) {
            startTime = LocalDateTime.now().minusDays(30);
        }
        if (endTime == null) {
            endTime = LocalDateTime.now();
        }
        
        return actionLogMapper.getModuleDistribution(startTime, endTime);
    }
    
    @Override
    public PageResult<UserLoginLog> pageLoginLogs(UserLoginLogQueryDTO queryDTO) {
        // 使用PageUtils处理分页参数
        int[] pageParams = PageUtils.handlePageParam(queryDTO.getPageNum(), queryDTO.getPageSize());
        int pageNum = pageParams[0];
        int pageSize = pageParams[1];
        
        // 使用PageHelper进行分页查询
        com.github.pagehelper.Page<UserLoginLog> page = com.github.pagehelper.PageHelper.startPage(pageNum, pageSize)
                .doSelectPage(() -> loginLogMapper.pageLoginLogs(queryDTO));
        
        // 构建分页结果
        return PageUtils.buildPageResult(pageNum, pageSize, page.getTotal(), page.getResult());
    }
}